package com.asa.photopicker.photo;

import java.util.List;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import com.asa.photopicker.LogUtils;
import com.asa.photopicker.R;
import com.asa.photopicker.photo.Folder.Media;

import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.CheckedTextView;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.ListView;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.TextView;

public abstract class MediaBaseFragment extends Fragment implements OnClickListener {
	private final static String TAG = "MediaBaseFragment";
	private final static int TYPE_CAMERA = 0;
	private final static int TYPE_IMAGE = 1;
	private GridView gvFolders;
	private AnimationLayout animLayout;
	private ListView lvContent;
	private TextView tvSelect;
	private View loadLayout;

	private int mImageSize;
	private List<Folder> mImageFolders;
	protected Folder mFolder;
	private ImageAdapter mImageAdapter;
	private FolderAdapter mFolderAdapter;

	protected Handler mainH;
	protected ThreadPoolExecutor mExecutor;
	private final static int PRIORITY_LOAD_IMAGE = 0, PRIORITY_SET_BITMAP = 1;
	private boolean mloadBitmapFlag = true;

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		mainH = new Handler();
		mExecutor = new ThreadPoolExecutor(2, 7, 10, TimeUnit.MICROSECONDS, new PriorityBlockingQueue<Runnable>());
		View root = inflater.inflate(getLayoutResId(), container, false);
		onInitView(root);
		return root;
	}

	protected void onInitView(View rootView) {
		mImageSize = Utils.getAdapterItemSize(3, Utils.dip2px(getActivity(), 1), Utils.getWidthPixels(getActivity()));
		gvFolders = (GridView) rootView.findViewById(R.id.gv_local_image_folder);
		lvContent = (ListView) rootView.findViewById(R.id.lv_folder);
		animLayout = (AnimationLayout) rootView.findViewById(R.id.anim_layout);
		tvSelect = (TextView) rootView.findViewById(R.id.tv_select);
		loadLayout = rootView.findViewById(R.id.layout_loading);
		tvSelect.setOnClickListener(this);
		rootView.findViewById(R.id.title_left_img).setOnClickListener(this);

		gvFolders.setOnScrollListener(new AbsListView.OnScrollListener() {

			@Override
			public void onScrollStateChanged(AbsListView view, int scrollState) {
				mloadBitmapFlag = scrollState == SCROLL_STATE_IDLE || scrollState == SCROLL_STATE_TOUCH_SCROLL;
				if (scrollState == SCROLL_STATE_IDLE && null != mImageAdapter) {
					mImageAdapter.notifyDataSetChanged();
				}
			}

			@Override
			public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
			}
		});
	}

	private class ImageAdapter extends BaseAdapter {
		private LayoutInflater mInflater;

		public ImageAdapter() {
			mInflater = LayoutInflater.from(getActivity());
		}

		@Override
		public int getCount() {
			int count = 0;
			if (showCamera()) {
				count = 1;
			}
			if (mFolder == null) {
				return count;
			}
			return mFolder.getCount() + count;
		}

		@Override
		public Media getItem(int position) {
			return mFolder.get(position);
		}

		@Override
		public int getViewTypeCount() {
			return showCamera() ? 2 : 1;
		}

		@Override
		public int getItemViewType(int position) {
			if (showCamera() && position == 0) {
				return TYPE_CAMERA;
			}
			return TYPE_IMAGE;
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			int type = getItemViewType(position);
			boolean isImage = type == TYPE_IMAGE;
			if (convertView == null) {
				convertView = mInflater.inflate(R.layout.adapter_image, null);
			}
			ViewHolder holder = (ViewHolder) convertView.getTag();
			if (holder == null) {
				holder = new ViewHolder();
				holder.iveAvatar = (ImageView) convertView.findViewById(R.id.ive_avatar);
				holder.mCtvAvatar = (CheckedTextView) convertView.findViewById(R.id.ctv_checked);
				LayoutParams lp = new LayoutParams(mImageSize, mImageSize);
				holder.iveAvatar.setLayoutParams(lp);
				convertView.setTag(holder);
			}
			if (isImage) {
				Media media;
				if (showCamera()) {
					media = getItem(position - 1);
				} else {
					media = getItem(position);
				}
				holder.iveAvatar.setScaleType(ScaleType.CENTER_CROP);
				setImagePath(holder.iveAvatar, media.getPath(), mImageSize, mImageSize);
				updateImageItem(convertView, isImage, position, media);
			} else {
				holder.iveAvatar.setScaleType(ScaleType.CENTER);
				holder.iveAvatar.setImageResource(R.drawable.camera);
				updateImageItem(convertView, false, position, null);
			}
			return convertView;
		}
	}

	protected void updateImageItem(View convertView, boolean isImage, int position, Media media) {

	}

	class FolderAdapter extends BaseAdapter {
		private int mImageSize;
		private LayoutInflater mInflater;

		public FolderAdapter() {
			mImageSize = Utils.getSmallSize(getActivity());
			mInflater = LayoutInflater.from(getActivity());
		}

		@Override
		public int getCount() {
			return Utils.isEmpty(mImageFolders) ? 0 : mImageFolders.size();
		}

		@Override
		public Folder getItem(int position) {
			return mImageFolders.get(position);
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(final int position, View convertView, ViewGroup parent) {
			if (convertView == null) {
				convertView = mInflater.inflate(R.layout.adapter_folder, null);
			}
			FolderHolder holder = (FolderHolder) convertView.getTag();
			if (holder == null) {
				holder = new FolderHolder();
				LayoutParams lp = new LayoutParams(mImageSize, mImageSize);
				holder.iveAvatar = (ImageView) convertView.findViewById(R.id.ive_avatar);
				holder.iveAvatar.setLayoutParams(lp);
				holder.tvName = (TextView) convertView.findViewById(R.id.tv_name);
				holder.tvNum = (TextView) convertView.findViewById(R.id.tv_num);
				holder.ivSelect = (ImageView) convertView.findViewById(R.id.iv_select);
				convertView.setTag(holder);
			}
			final Folder folder = getItem(position);
			String nums = getString(R.string.total_x_photo, folder.getCount());
			holder.tvName.setText(folder.getName());
			holder.tvNum.setText(nums);
			holder.ivSelect.setVisibility(mFolder == folder ? View.VISIBLE : View.GONE);
			setImagePath(holder.iveAvatar, folder.getChild(), mImageSize, mImageSize);
			convertView.setOnClickListener(new OnClickListener() {

				@Override
				public void onClick(View v) {
					loadFolder(folder);
				}
			});
			return convertView;
		}
	}

	protected void setImagePath(final ImageView view, final String path, final int width, final int height) {
		view.setImageResource(R.drawable.image_default);

		final String id = generateId(path, width, height);
		Bitmap thumb = Utils.getBitmapCache().get(id);
		LogUtils.d(TAG, "%s, flag: %s , id: %s", null != thumb, mloadBitmapFlag, id);
		if (null != thumb) {
			view.setImageBitmap(thumb);
			return;
		}

		if (!mloadBitmapFlag) {
			return;
		}
		Runnable task = new Runnable() {

			@Override
			public void run() {
				final Bitmap thumb = Utils.getImageThumbnail(path, width, height);
				mainH.post(new Runnable() {

					@Override
					public void run() {
						if (null != thumb) {
							view.setImageBitmap(thumb);
							Utils.getBitmapCache().put(id, thumb);
						} else {
							view.setImageResource(R.drawable.image_default);
						}
					}
				});
			}
		};
		mExecutor.execute(new TaskWithPriority(task, PRIORITY_SET_BITMAP));
	}

	private String generateId(String path, int width, int height) {
		if (width < 1 || height < 1) {
			return path;
		}
		return String.format("_%s#%dx%d", path, width, height);
	}

	protected void loadFolder(Folder folder) {
		mFolder = folder;
		tvSelect.setText(folder.getName());
		handFolderAdapter();
		handleImageAdapter();
		animLayout.dismiss();
	}

	class FolderHolder {
		ImageView iveAvatar;
		TextView tvName;
		TextView tvNum;
		ImageView ivSelect;
	}

	protected class ViewHolder {
		ImageView iveAvatar;
		CheckedTextView mCtvAvatar;
	}

	public void onLoadData() {
		Runnable task = new Runnable() {

			@Override
			public void run() {
				final List<Folder> folders = Utils.getImageFolders(getActivity(), getString(R.string.all_photo));
				mainH.post(new Runnable() {

					@Override
					public void run() {
						onDataArrived(200, folders);
					}
				});
			}
		};
		mExecutor.execute(new TaskWithPriority(task, PRIORITY_LOAD_IMAGE));
	}

	public int onDataArrived(int statusCode, List<Folder> value) {
		if (!isAdded()) {
			return 0;
		}
		loadLayout.setVisibility(View.GONE);
		mImageFolders = value;
		if (!Utils.isEmpty(value)) {
			mFolder = value.get(0);
		}
		handFolderAdapter();
		handleImageAdapter();
		return statusCode;
	}

	protected void handleImageAdapter() {
		if (mImageAdapter == null) {
			mImageAdapter = new ImageAdapter();
			gvFolders.setAdapter(mImageAdapter);
		} else {
			mImageAdapter.notifyDataSetChanged();
		}
	}

	protected void handFolderAdapter() {
		if (mFolderAdapter == null) {
			mFolderAdapter = new FolderAdapter();
			lvContent.setAdapter(mFolderAdapter);
		} else {
			mFolderAdapter.notifyDataSetChanged();
		}
	}

	@Override
	public void onStop() {
		if (animLayout.isShowing()) {
			animLayout.dismiss();
		}
		if (null != mExecutor) {
			mExecutor.shutdown();
			// tHandler.getLooper().quit();
		}
		super.onStop();
	}

	protected boolean showCamera() {
		return false;
	}

	protected boolean isSelectAvatar() {
		if (Utils.isEmpty(mImageFolders)) {
			return true;
		}
		if (mImageFolders.indexOf(mFolder) == 0) {
			return true;
		}
		return false;
	}

	@Override
	public void onClick(View v) {
		int id = v.getId();
		if (id == R.id.tv_select) {
			animLayout.show();
		} else if (id == R.id.title_left_img) {
			getActivity().onBackPressed();
		}
	}

	protected abstract int getLayoutResId();

}
